package com.ruoyi.web.controller;


import com.alibaba.fastjson.JSON;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.ijpay.core.enums.SignType;
import com.ijpay.core.enums.TradeType;
import com.ijpay.core.kit.HttpKit;
import com.ijpay.core.kit.IpKit;
import com.ijpay.core.kit.WxPayKit;
import com.ijpay.wxpay.WxPayApi;
import com.ijpay.wxpay.WxPayApiConfig;
import com.ijpay.wxpay.WxPayApiConfigKit;
import com.ijpay.wxpay.model.RefundModel;
import com.ijpay.wxpay.model.RefundQueryModel;
import com.ijpay.wxpay.model.UnifiedOrderModel;
import com.jfinal.kit.StrKit;
import com.ruoyi.utils.ResponseResult;
import com.ruoyi.vo.WxPayBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@RequestMapping("pay")
@RestController
public class PayController extends AbstractWxPayApiController{

    public static Cache<String,String> applyCache = CacheBuilder.newBuilder().maximumSize(600).expireAfterWrite(60,TimeUnit.MINUTES).build();

    @Autowired
    private WxPayBean wxPayBean;

    private String notifyUrl;
    private String refundNotifyUrl;
    @Override
    public WxPayApiConfig getApiConfig() {
        WxPayApiConfig apiConfig;

        try {
            apiConfig = WxPayApiConfigKit.getApiConfig(wxPayBean.getAppId());
        } catch (Exception e) {
            System.out.println("wxPayBean.getCertPath():"+wxPayBean.getCertPath());
            apiConfig = WxPayApiConfig.builder()
                    .appId(wxPayBean.getAppId())
                    .mchId(wxPayBean.getMchId())
                    .partnerKey(wxPayBean.getPartnerKey())
                    .certPath(wxPayBean.getCertPath())
                    .domain(wxPayBean.getDomain())
                    .build();
        }
        notifyUrl = apiConfig.getDomain().concat("/pay/payNotify");
        refundNotifyUrl = apiConfig.getDomain().concat("/pay/refundNotify");
        return apiConfig;
    }


    /**
     * 微信小程序支付
     */
    @RequestMapping(value = "/miniAppPay", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public ResponseResult miniAppPay(HttpServletRequest request) {
        //需要通过授权来获取openId
        String openId = request.getParameter("openId");
        System.out.println("openI=>"+openId);
        String ip = IpKit.getRealIp(request);
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }
        WxPayApiConfigKit.putApiConfig(getApiConfig());
        WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
        String tradeno = WxPayKit.generateStr();
        Map<String, String> params = UnifiedOrderModel
                .builder()
                .appid(wxPayApiConfig.getAppId())
                .mch_id(wxPayApiConfig.getMchId())
                .nonce_str(WxPayKit.generateStr())
                .body("御医堂收款")
                .attach("御医堂")
                .out_trade_no(tradeno)
                .total_fee("1")
                .spbill_create_ip(ip)
//                .notify_url(notifyUrl)
                .trade_type(TradeType.JSAPI.getTradeType())
                .openid(openId)
                .build()
                .createSign(wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);

        String xmlResult = WxPayApi.pushOrder(false, params);

//        log.info(xmlResult);
        Map<String, String> result = WxPayKit.xmlToMap(xmlResult);

        String returnCode = result.get("return_code");
        String returnMsg = result.get("return_msg");

        if (!WxPayKit.codeIsOk(returnCode)) {
//            return new AjaxResult().addError();
            return  ResponseResult.failure(returnMsg);
        }
        String resultCode = result.get("result_code");
        if (!WxPayKit.codeIsOk(resultCode)) {
            return  ResponseResult.failure(returnMsg);

        }
        // 以下字段在 return_code 和 result_code 都为 SUCCESS 的时候有返回
        String prepayId = result.get("prepay_id");

        Map<String, String> packageParams = WxPayKit.miniAppPrepayIdCreateSign(wxPayApiConfig.getAppId(), prepayId,
                wxPayApiConfig.getPartnerKey(), SignType.HMACSHA256);
        String jsonStr = JSON.toJSONString(packageParams);
//        log.info("小程序支付的参数:" + jsonStr);
//        applyCache.put(tradeno, tel+"#"+userName+"#"+activtyId+"#"+admissionYear+"#"+graduateYear+"#"+openId);
        return  ResponseResult.success(jsonStr);
    }

    /**
     * 微信退款
     */
//    @RequestMapping(value = "/refund", method = {RequestMethod.POST, RequestMethod.GET})
//    @ResponseBody
//    public String refund(@RequestParam(value = "transactionId", required = false) String transactionId,
//                         @RequestParam(value = "outTradeNo", required = false) String outTradeNo) {
////
//        outTradeNo = "sas";
//        String fee= "1000";
//        try {
////            log.info("transactionId: {} outTradeNo:{}", transactionId, outTradeNo);
//
//            if (StrKit.isBlank(outTradeNo) && StrKit.isBlank(transactionId)) {
//                return "transactionId、out_trade_no二选一";
//            }
//            WxPayApiConfigKit.putApiConfig(getApiConfig());
//            WxPayApiConfig wxPayApiConfig = WxPayApiConfigKit.getWxPayApiConfig();
//            System.out.println(".getAppId()"+wxPayApiConfig.getAppId());
//            System.out.println(".getMchId()"+wxPayApiConfig.getMchId());
//            System.out.println(".nonce_str()"+WxPayKit.generateStr());
//            System.out.println("transaction_id()"+transactionId);
//            System.out.println("notify_url()"+refundNotifyUrl);
//            Map<String, String> params = RefundModel.builder()
//                    .appid(wxPayApiConfig.getAppId())
//                    .mch_id(wxPayApiConfig.getMchId())
//                    .nonce_str(WxPayKit.generateStr())
//                    .out_trade_no("25d5e953517244d78b1f4261e8250e5f")
//                    .out_refund_no("25d5e953517244d78b1f4261e8250e5f")
//                    .total_fee("1000")
//                    .refund_fee("1000")
//                    .refund_desc("退款")
//                    .notify_url(refundNotifyUrl)
//                    .build()
//                    .createSign(wxPayApiConfig.getPartnerKey(), SignType.MD5);
//            String classpath = ResourceUtils.getURL("classpath:").getPath();
//            String certPath = "/Users/jie/Desktop/gs/yytapp/yyt-shop-api/src/main/resources/apiclient_cert.p12";
//            String refundStr = WxPayApi.orderRefund(false, params, certPath, wxPayApiConfig.getMchId());
//            System.out.println("refundStr: {}"+refundStr);
//            Map<String, String> result = WxPayKit.xmlToMap(refundStr);
//            if(result.get("result_code").equals("FAIL")) {
//                System.out.println("code"+1);
//
//            }else {
//                System.out.println("code"+0);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return null;
//    }
//    /**
//     * 退款通知
//     */
//    @RequestMapping(value = "/refundNotify", method = {RequestMethod.POST, RequestMethod.GET})
//    @ResponseBody
//    public String refundNotify(HttpServletRequest request) {
//        String xmlMsg = HttpKit.readData(request);
////        log.info("退款通知=" + xmlMsg);
//        System.out.println("退款通知=" + xmlMsg);
//        Map<String, String> params = WxPayKit.xmlToMap(xmlMsg);
//
//        String returnCode = params.get("return_code");
//        // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
//        if (WxPayKit.codeIsOk(returnCode)) {
//            String reqInfo = params.get("req_info");
//            WxPayApiConfigKit.putApiConfig(getApiConfig());
//            String decryptData = WxPayKit.decryptData(reqInfo, WxPayApiConfigKit.getWxPayApiConfig().getPartnerKey());
////            log.info("退款通知解密后的数据=" + decryptData);
//            // 更新订单信息
//            // 发送通知等
//            Map<String, String> xml = new HashMap<String, String>(2);
//            xml.put("return_code", "SUCCESS");
//            xml.put("return_msg", "OK");
//            Map<String, String> refundMap = WxPayKit.xmlToMap(decryptData);
//            String out_trade_no = refundMap.get("out_trade_no");
//            String out_refund_no = refundMap.get("out_refund_no");
//            String refund_fee = refundMap.get("refund_fee");
//            String success_time = refundMap.get("success_time");
////            List<ActivityApplyEntity> list = activityApplyService.select(ACTIVITYAPPLYTB.OUT_TRADE_NO.eq(out_trade_no), ACTIVITYAPPLYTB.CREATE_TIME.desc());
////            if(list.size()==1) {
////                ActivityApplyEntity aae = list.get(0);
////                if(aae.getRefundFee()==null) {
////                    aae.setRefundFee(new BigDecimal(refund_fee));
////                    aae.setOutRefundNo(out_refund_no);
////                    aae.setRefundTime(LocalDateTime.parse(success_time,Constant.dateTimeDtf));
////                    activityApplyService.update(aae);
////                }
////            }
//
//            return WxPayKit.toXml(xml);
//        }
//        return null;
//    }
}
